package legoserver;


import java.awt.*;
import java.io.*;
import javax.swing.*;

/**
 * special implementation of data type map
 */
public class AStarMap implements Serializable {
  int w = 40;
  int h = 40;
  AStarGridCell gridCell[][] = new AStarGridCell[w][h];

  /**
   * constructor builds an array of grid cells
   */
  public AStarMap() {
    super();
    //setLayout(new GridLayout(w, h));
    for (int i = 0; i < w; i++) {
      for (int j = 0; j < h; j++) {
        gridCell[j][i] = new AStarGridCell();
        gridCell[j][i].setPosition(new Point(j, i));
        //add(gridCell[j][i]);
      }
    }
  }

  /**
   * sets the cost of a block in the cell x, y
   * @param x int coordinate
   * @param y int coordinate
   * @param cost double value
   */
  public void setBlock(int x, int y, double cost) {
    gridCell[x][y].setCost(cost);
  }

  /**
   * gets position of the start cell
   * @return point start position
   */
  public Point getStartPosition() {    
    AStarGridCell start = AStarGridCell.getStartCell();
    return start.getPosition();
  }
  
  /**
   * get neighbour cells of the cell g
   * @param g grid cell
   * @return array of neighbour cells
   */
  public AStarGridCell[] getAdjacent(AStarGridCell g) {
    AStarGridCell next[] = new AStarGridCell[4];
    Point p = g.getPosition();
    if (p.y != 0) { next[0] = gridCell[p.x][p.y - 1]; }
    if (p.x != w - 1) { next[1] = gridCell[p.x + 1][p.y]; }
    if (p.y != h - 1) { next[2] = gridCell[p.x][p.y + 1]; }
    if (p.x != 0) { next[3] = gridCell[p.x - 1][p.y]; }
    return next;
  }

  /**
   * get neighbour cells with lowest distance
   * @param g grid cell
   * @return nearest neighbour cell
   */
  public AStarGridCell getLowestAdjacent(AStarGridCell g) {
    AStarGridCell next[] = getAdjacent(g);
    AStarGridCell small = next[0];
    double dist = Double.MAX_VALUE;
    for (int i = 0; i < 4; i++) {
      if (next[i] != null){
        double nextDist = next[i].getDistFromStart();
        if (nextDist < dist && nextDist >= 0) {
          small = next[i];
          dist = next[i].getDistFromStart();
        }
      }
    }
    return small;
  }

  /**
   * reads an object from an object stream
   * @param ois stream
   */
  private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    AStarGridCell.tidy = false;
    ois.defaultReadObject();
    AStarGridCell.setShowPath(false);
  }
}
